<?php
namespace app\api\logic;

use app\api\consDir\ErrorConst;
use app\api\consDir\SandConst;
use app\api\services\MemberService;
use app\api\services\OrderService;
use app\api\services\PayService;
use app\api\services\RabbitMqService;
use app\api\services\ShopService;
use app\common\libs\Singleton;
use app\common\models\Member\Account;
use app\common\models\Order\Order;
use app\common\models\Order\OrderGoods;
use app\common\models\Order\OrderShop;
use app\common\models\Shop\Shop;
use app\common\utils\CommonUtil;
use app\common\utils\RedLock;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

/**
 * 支付模块
 */
class PayLogic extends BaseLogic
{
    use Singleton;

    /**
     * @param $orderNo
     * @param $payType
     * @param $payPassword
     * @param $paySubType
     * @return array|mixed|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function payOrder($orderNo, $payType, $payPassword, $paySubType)
    {
        if ( ! RedLock::getInstance()->lock('payOrder_' . $this->userinfo->id, 3)) {
            CommonUtil::throwException(ErrorConst::FREQUENT_ERROR, ErrorConst::FREQUENT_ERROR_MSG);
        }
        /*if ($payType != 1) {
            CommonUtil::throwException(ErrorConst::PARAM_ERROR, ErrorConst::PARAM_ERROR_MSG);
        }*/

        $shopId = OrderShop::getInstance()->where('order_no',$orderNo)->value('shop_id');
        $shopUserId = Shop::getInstance()->where('id',$shopId)->value('user_id');
        if($shopUserId){
            $account = Account::getInstance()->where('user_id',$shopUserId)->find();
            if(empty($account) || $account['isActiveSd'] == 0){
                CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '商家未绑定电子钱包');
            }
        }

        if ($payType == 3) {
            $account = MemberService::getInstance()->account($this->userinfo->id);
            if (empty($account)) {
                CommonUtil::throwException(ErrorConst::NO_PAY_PASSWORD_ERROR, ErrorConst::NO_PAY_PASSWORD_ERROR_MSG);
            }

            //验证支付密码
            if ($account['payPwd'] != $payPassword) {
                CommonUtil::throwException(ErrorConst::PAY_PASSWORD_ERROR, ErrorConst::PAY_PASSWORD_ERROR_MSG);
            }
        }

        $order = OrderService::getInstance()->getOrderInfo($orderNo, $this->userinfo->id);
        if (empty($order)) {
            CommonUtil::throwException(ErrorConst::NO_ORDER_ERROR, ErrorConst::NO_ORDER_ERROR_MSG);
        }
        if ($order['status'] != 0) {
            CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, ErrorConst::ORDER_STATUS_ERROR_MSG);
        }
        //平台抵扣券
        if($order['deduction'] > 0){
            $finance = MemberService::getInstance()->finance($this->userinfo->id);
            if($finance['deduction'] < $order['deduction']){
                CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '平台抵扣券不足');
            }
        }
        $isBalance = 0;

        Order::getInstance()->where('order_no', $orderNo)->update([
            'pay_type' => $payType,
        ]);
        $payInfo = PayService::getInstance()->payOrder($this->userinfo->id, $order, $payType);
        if ($payType == 3) {
            $userBalance = MemberService::getInstance()->finance($this->userinfo->id);
            if ($payInfo['pay_price'] > $userBalance['amount']) {
                CommonUtil::throwException(ErrorConst::ORDER_STATUS_ERROR, '余额不足');
            }
            $isBalance = 1;
        }
        /*if (!empty($order['couponId'])) {
            $coupon = CouponService::getInstance()->getCouponInfo($order['couponId'], $this->userinfo->id);
            if (empty($coupon)) {
                CommonUtil::throwException(ErrorConst::COUPON_NOT_ERROR, ErrorConst::COUPON_NOT_ERROR_MSG);
            }
        }*/
        //$payInfo['pay_price'] = env('test.is_test') ? 0.01 : $payInfo['pay_price'];
        $userInfo = MemberService::getInstance()->getUserInfo($this->userinfo->id);
        if ($payType == 3) {
            //余额全付
            $info = [
                'pay_status' => 3,
                'pay_no' => $payInfo['pay_no'],
                'money' => $payInfo['pay_price'],
                'trade_no' => '',
                'receipt_data' => '',
            ];
            //$info = PayService::getInstance()->payFormOrder($info);
            $event["exchange"] = config('rabbitmq.order_callback_queue');
            RabbitMqService::send($event, $info);
            $pay = [];
            Order::getInstance()->where('order_no', $orderNo)->update([
                'is_direct' => 0,
            ]);
        } elseif ($payType == 4) {
            //电子钱包
            $fee = ShopService::getInstance()->IsDirectByOrderNo($orderNo);
            //最高服务费
            $maxFee = bcmul($payInfo['pay_price'],0.08,2);
            if($order['deduction'] > 0){
                $fee = bcadd($fee,$order['deduction'],2);
            }
            //少于8%
            if($fee >= 0 && $fee <= $maxFee){
                $isDirect = 1;
                //直接转给商家
                //$fee = env('test.is_test') ? 0.01 : $fee;
                Log::error('pay_price:'.$payInfo['pay_price'].'fee:'.$fee);
                $pay = SandLogic::getInstance()->transfer($payInfo['pay_price'], SandConst::PREFIX . $this->userinfo->id, SandConst::PREFIX . $shopUserId, $fee, $payInfo['pay_no'], 'confirm');
            }else{
                $isDirect = 0;
                //平台收款
                $pay = SandLogic::getInstance()->orderCreate($this->userinfo->id, $payInfo['pay_price'], $payInfo['pay_no']);
            }
            Order::getInstance()->where('order_no', $orderNo)->update(['is_direct' => $isDirect]);
        } elseif ($payType == 5) {
            $pay = SandLogic::getInstance()->orderCreateScan($payInfo['pay_price'], $payInfo['pay_no']);
        } else {
            $pay = PayService::getInstance()->toPay($payInfo, $userInfo, $payType, $paySubType);
        }
        return ['payInfo' => $pay, 'isBalance' => $isBalance];
    }

}
